﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
using Unity.Collections;
using UnityEngine;
/// <summary>
/// AssetBundle资源包架构
/// </summary>
[XmlRoot("ESF_Xml_AssetBundleSchema")]
public class ESF_Xml_AssetBundleSchema : AbsESF_Xml
{
    /// <summary>
    /// 场景内联资源名称后缀
    /// </summary>
    [XmlElement("场景内联资源名称后缀")]
    [ReadOnly]
    public string sceneInlineDepSuffix = "_inlineDep";
    /// <summary>
    /// 场景引用资源名称后缀
    /// </summary>
    [XmlElement("场景引用资源名称后缀")]
    [ReadOnly]
    public string sceneRefDepSuffix = "_refDep";
    /// <summary>
    /// 对象引用资源名称后缀
    /// </summary>
    [XmlElement("对象引用资源名称后缀")]
    [ReadOnly]
    public string objectRefDepSuffix = "_objDep";
    /// <summary>
    /// 强制AssetBundle根资源
    /// </summary>
    [XmlElement("强制AssetBundle根资源")]
    [ESF_GUIOperation()]
    [ESF_GUISeparator()]
    [ESF_ArrayMaxLength(typeof(enESF_UnityFileExt))]
    public enESF_UnityFileExt[] forceAssetBundleRootExts;
    /// <summary>
    /// 忽略设置AssetBundle名称资源
    /// </summary>
    [XmlElement("忽略设置AssetBundle名称资源")]
    [ReadOnly]
    [ESF_ArrayMaxLength(typeof(enESF_UnityFileExt))]
    public enESF_UnityFileExt[] ignoreNameExts;
    /// <summary>
    /// 名称前缀
    /// </summary>
    [XmlElement("名称前缀")]
    [ESF_GUIOperation()]
    [ESF_GUISeparator()]
    [ESF_ArrayMaxLength(typeof(enESF_UnityFileExt))]
    public ESF_Xml_AssetBundleSchema_NamePrefix[] namePrefixs;
    /// <summary>
    /// 锁定名称资源
    /// </summary>
    [XmlElement("锁定名称资源")]
    [ESF_AliasTooltip("锁定名称资源", "名称锁定后资源为单独AssetBundle文件")]
    [ESF_GUIOperation()]
    [ESF_GUISeparator()]
    [ESF_ArrayMaxLength(typeof(enESF_UnityFileExt))]
    public enESF_UnityFileExt[] lockNameExts;

    /// <summary>
    /// 忽略设置AssetBundle名称文件
    /// </summary>
    [XmlElement("忽略设置AssetBundle名称文件")]
    [ESF_GUIOperation()]
    [ESF_GUISeparator()]
    public ESF_Xml_AssetBundleSchema_IgnoreFiles[] ignoreFiles;

    /// <summary>
    /// 允许设置AssetBundle名称的后缀
    /// </summary>
    static Dictionary<enESF_UnityFileExt, bool> mAllowAbExts = typeof(enESF_UnityFileExt).ESF_EnumToSpecialValue<enESF_UnityFileExt, ESF_IgnoreSetAssetBundleAttribute, bool>((e, a) => { return a == null; });
    
    /// <summary>
    /// AssetBundle包名称前缀
    /// </summary>
    static Dictionary<enESF_UnityFileExt, string> mAbsNamePrefixs = new Dictionary<enESF_UnityFileExt, string>();

    /// <summary>
    /// 锁定名称后缀
    /// </summary>
    static List<enESF_UnityFileExt> mLockNameExts = new List<enESF_UnityFileExt>();

    /// <summary>
    /// 忽略后缀
    /// </summary>
    static List<enESF_UnityFileExt> mIgnoreExts = new List<enESF_UnityFileExt>();
    /// <summary>
    /// 忽略的文件
    /// </summary>
    static List<string> mIgnoreFiles = new List<string>();
    /// <summary>
    /// 强制AssetBundle根资源
    /// </summary>
    static List<enESF_UnityFileExt> mForceAssetBundleRootExts = new List<enESF_UnityFileExt>();
    /// <summary>
    /// OnResolve
    /// </summary>
    protected override void OnResolve()
    {
        mIgnoreExts.Clear();
        foreach (var key in mAllowAbExts)
        {
            if (!key.Value)
            {
                mIgnoreExts.Add(key.Key);
            }
        }
        ignoreNameExts = mIgnoreExts.ToArray();
        mLockNameExts.Clear();
        if (lockNameExts != null && lockNameExts.Length > 0)
        {
            mLockNameExts = lockNameExts.ToList();
        }
        if (namePrefixs != null)
        {
            foreach (var key in namePrefixs)
            {
                mAbsNamePrefixs.Add(key.fileExt, key.abNamePrefix);
            }
        }
        mForceAssetBundleRootExts.Clear();
        if (forceAssetBundleRootExts != null && forceAssetBundleRootExts.Length > 0)
        {
            mForceAssetBundleRootExts = forceAssetBundleRootExts.ToList();
        }
        mIgnoreFiles.Clear();
        if (ignoreFiles != null && ignoreFiles.Length > 0)
        {
            foreach (var key in ignoreFiles)
            {
                string fn = $"{key.fileName}{key.fileExt.ESF_FirstAttribute<ESF_FileExtAttribute>().ext}".ToLower();
                if (!mIgnoreFiles.Contains(fn))
                {
                    mIgnoreFiles.Add(fn);
                }
            }
        }
    }

    /// <summary>
    /// 是否锁定名称后缀
    /// </summary>
    /// <param name="_ext">后缀</param>
    /// <returns>true:是,false:否</returns>
    public bool isLockNameExt(enESF_UnityFileExt _ext)
    {
        return mLockNameExts.Contains(_ext);
    }

    /// <summary>
    /// 是否允许指定后缀文件设置AssetBundle名称
    /// </summary>
    /// <param name="_ext">文件后缀</param>
    /// <returns>true:允许设置AssetBundle名称,false:不允许设置AssetBundle名称</returns>
    public bool IsAllowSetAssetBundle(enESF_UnityFileExt _ext)
    {
        return !mIgnoreExts.Contains(_ext);
    }

    /// <summary>
    /// 是否允许指定的文件【带文件后缀】设置AssetBundle名称
    /// </summary>
    /// <param name="_fileName">文件名称</param>
    /// <returns>true:允许设置AssetBundle名称,false:不允许设置AssetBundle名称</returns>
    public bool IsAllowSetAssetBundle(string _fileName)
    {
        return !mIgnoreFiles.Contains(_fileName.ToLower());
    }

    /// <summary>
    /// 是否强制AssetBundle根资源
    /// </summary>
    /// <param name="_ext">文件后缀</param>
    /// <returns>true:是强制AssetBundle根资源,false:不是强制AssetBundle根资源</returns>
    public bool IsForceAssetBundleRoot(enESF_UnityFileExt _ext)
    {
        return mForceAssetBundleRootExts.Contains(_ext);
    }
}

/// <summary>
/// AssetBundle包名称前缀
/// </summary>
[Serializable]
[XmlRoot("ESF_Xml_AssetBundleSchema_NamePrefix")]
public class ESF_Xml_AssetBundleSchema_NamePrefix
{
    /// <summary>
    /// 文件后缀
    /// </summary>
    [XmlElement("文件后缀")]
    [ESF_NoDuplicateValue()]
    public enESF_UnityFileExt fileExt;
    /// <summary>
    /// AB包前缀
    /// </summary>
    [XmlElement("AB包前缀")]
    public string abNamePrefix;
}

/// <summary>
/// 忽略AssetBundle包名称的文件
/// </summary>
[Serializable]
[XmlRoot("ESF_Xml_AssetBundleSchema_IgnoreFiles")]
public class ESF_Xml_AssetBundleSchema_IgnoreFiles
{
    /// <summary>
    /// 文件名称
    /// </summary>
    [XmlElement("文件名称")]
    public string fileName;
    /// <summary>
    /// 文件后缀
    /// </summary>
    [XmlElement("文件后缀")]    
    public enESF_UnityFileExt fileExt;    
}
#endif

